From 1ff86d11ac18ee6bccc4aeb40ab00c7a4eff3444 Mon Sep 17 00:00:00 2001 From: robertl Date: Thu, 11 Nov 2004 20:33:14 +0000 Subject: [PATCH] From justin: add writing to coastexp.c --- gpsbabel/Makefile | 3 +- gpsbabel/coastexp.c | 389 ++++++++++++++++++++++---------- gpsbabel/reference/coastexp.ref | 41 ++++ gpsbabel/testo | 12 + gpsbabel/xmlgeneric.c | 37 +++ 5 files changed, 367 insertions(+), 115 deletions(-) diff --git a/gpsbabel/Makefile b/gpsbabel/Makefile index 70820dc64..ecf6750e6 100644 --- a/gpsbabel/Makefile +++ b/gpsbabel/Makefile @@ -45,7 +45,7 @@ COLDSYNC=coldsync/util.o coldsync/pdb.o SHAPE=shapelib/shpopen.o shapelib/dbfopen.o LIBOBJS = queue.o route.o waypt.o filter_vecs.o util.o vecs.o mkshort.o \ - csv_util.o grtcirc.o vmem.o util_crc.o xmlgeneric.o \ + csv_util.o grtcirc.o vmem.o util_crc.o xmlgeneric.o uuid.o \ $(COLDSYNC) $(GARMIN) $(JEEPS) $(SHAPE) $(FMTS) $(FILTERS) OBJS = main.o $(LIBOBJS) @@ -166,6 +166,7 @@ mapsend.o: mapsend.c defs.h queue.h mapsend.h magellan.h mapsource.o: mapsource.c defs.h queue.h garmin_tables.h mkshort.o: mkshort.c defs.h queue.h navicache.o: navicache.c defs.h queue.h +coastexp.o: coastexp.c defs.h queue.h netstumbler.o: netstumbler.c defs.h queue.h csv_util.h nmea.o: nmea.c defs.h queue.h ozi.o: ozi.c defs.h queue.h csv_util.h diff --git a/gpsbabel/coastexp.c b/gpsbabel/coastexp.c index b8e19ecdc..aa8aaf0a4 100755 --- a/gpsbabel/coastexp.c +++ b/gpsbabel/coastexp.c @@ -22,12 +22,17 @@ #include static XML_Parser psr; #endif +#include + +#include "uuid.h" FILE *fd; FILE *ofd; #define MYNAME "coastexp" #define MY_CBUF 4096 +#define MY_TBUF 64 +#define MY_UBUF 128 #if NO_EXPAT void @@ -42,107 +47,114 @@ ce_read(void) } #else +static void *mkshort_handle; // short-name handle static char *element; // Current element being parsed static char *cdatastr; // Current XML character data being built up (until a ) /* CE-specific mark structure - used for both route marks and standalone marks */ struct CE_MARK { - struct CE_MARK *next; // pointer to next mark in list + queue Q; char *id; // CE's mark ID (of the form "{}") - waypoint *wp; // GPSBabel waypoint + char *created; // CE's creation time (of the form "
TZ") + waypoint *wp; // GPSBabel waypoint int used; // Is this mark used in a route or not? }; typedef struct CE_MARK ce_mark; /* CE-specific route structure */ struct CE_ROUTE { - struct CE_ROUTE *next; // pointer to next route in list - char *id; // CE's route ID (of the form "{}") + queue Q; + char *id; // CE's route ID (of the form "{}") route_head *r; // GPSBabel route header - ce_mark *marks; // list of CE marks in this route + queue ce_mark_head; // list of CE marks in this route }; typedef struct CE_ROUTE ce_route; -static ce_route *routes = NULL; // List of routes currently found +static queue ce_route_head; // List of routes currently found static ce_route *currentRoute = NULL; // Current route being processed -static ce_mark *marks = NULL; // List of stand-alone marks currently found -static ce_mark *currentMark = NULL; // Current mark being processed -static int inRoute = 0; // Are we processing a route? -static int inMark = 0; // Are we processing a mark? +static queue ce_mark_head; // List of stand-alone marks currently found +static ce_mark *currentMark = NULL; // Current mark being processed +static char *time_buffer = NULL; // Time buffer for processing times +static char *uuid_buffer = NULL; // UUID buffer for processing uuid's +static int inRoute = 0; // Are we processing a route? +static int inMark = 0; // Are we processing a mark? /* Add a route to the list of routes */ static void add_route(ce_route *route) { - if (routes == NULL) { - routes = route; - } else { - ce_route *curr = routes; - while (curr->next != NULL) - curr = curr->next; - curr->next = route; - } + ENQUEUE_TAIL(&ce_route_head, &route->Q); } /* Add a mark to the list of stand-alone marks */ static void add_mark(ce_mark *mark) { - if (marks == NULL) { - marks = mark; - } else { - ce_mark *curr = marks; - while (curr->next != NULL) - curr = curr->next; - curr->next = mark; - } + ENQUEUE_TAIL(&ce_mark_head, &mark->Q); } /* Add a mark to the specified route */ static void add_mark_to_route(ce_route *route, ce_mark *mark) { - if (route->marks == NULL) { - route->marks = mark; - } else { - ce_mark *curr = route->marks; - while (curr->next != NULL) - curr = curr->next; - curr->next = mark; + ENQUEUE_TAIL(&route->ce_mark_head, &mark->Q); +} + +/* Free a mark */ +static void +free_mark(ce_mark *mark) +{ + xfree(mark->id); + if (mark->created) + xfree(mark->created); + xfree(mark); +} + +/* Free a route */ +static void +free_route(ce_route *route) +{ + queue *elem, *tmp; + QUEUE_FOR_EACH(&route->ce_mark_head, elem, tmp) { + ce_mark *mark = (ce_mark *) elem; + free_mark(mark); } + xfree(route->id); + xfree(route); + // Don't free the waypoint since this is done elsewhere } /* Start processing an XML item */ static void ce_start(void *data, const char *el, const char **attr) { - element = xstrdup(el); + const char **ap; + strcpy(element, el); if (0 == strcmp(el, "Route")) { inRoute = 1; - const char **ap; for (ap = attr; *ap; ap+=2) { if (0 == strcmp(ap[0], "id")) { // Create a CE route object and add it to the list of routes currentRoute = (ce_route *) xcalloc(sizeof (ce_route), 1); - currentRoute->next = NULL; currentRoute->id=xstrdup(ap[1]); currentRoute->r = route_head_alloc(); - currentRoute->marks = NULL; + QUEUE_INIT(¤tRoute->ce_mark_head); add_route(currentRoute); } } } else if (0 == strcmp(el, "Mark")) { inMark = 1; - const char **ap; + currentMark = (ce_mark *) xcalloc(sizeof (ce_mark), 1); + currentMark->wp = NULL; + currentMark->used = 0; + add_mark(currentMark); for (ap = attr; *ap; ap+=2) { if (0 == strcmp(ap[0], "id")) { // Create a CE mark object and add it to the list of stand-alone marks - currentMark = (ce_mark *) xcalloc(sizeof (ce_mark), 1); - currentMark->next = NULL; - currentMark->id=xstrdup(ap[1]); - currentMark->wp = NULL; - currentMark->used = 0; - add_mark(currentMark); + currentMark->id = xstrdup(ap[1]); + } + else if (0 == strcmp(ap[0], "created")) { + currentMark->created = xstrdup(ap[1]); } } } @@ -163,12 +175,13 @@ static void ce_cdata(void *dta, const XML_Char *s, int len) { if (*s != '\n') { + char *edatastr; // We buffer up characters in 'cdatastr' until a single is received if ((strlen(cdatastr) + len) > MY_CBUF) { printf("Buffer overflow - line too long!"); exit(-1); } - char *edatastr = cdatastr+strlen(cdatastr); + edatastr = cdatastr+strlen(cdatastr); memcpy(edatastr, s, len); edatastr[len] = '\0'; } else { @@ -179,52 +192,90 @@ ce_cdata(void *dta, const XML_Char *s, int len) if (strlen(s) <= 0) return; if (0 == strcmp(element, "Marks")) { - if (inRoute == 1) { + if (inRoute) { // We are processing the marks in a route so create a CE mark object // and add it to the current route ce_mark *mark = (ce_mark *) xcalloc(sizeof (ce_mark), 1); - mark->next = NULL; mark->id = xstrdup(s); + mark->created = NULL; mark->wp = NULL; add_mark_to_route(currentRoute, mark); } } else if (0 == strcmp(element, "Position")) { - if (inMark == 1) { + if (inMark) { // We are processing a standalone mark so read the lat/long position // and create a waypoint to add to the current mark char *position = xstrdup(s); char *lat = position; char *latNorS = position; + char *lng; + char *longEorW; while (*latNorS != ' ') latNorS++; *latNorS++ = '\0'; - char *lng = latNorS; + lng = latNorS; lng++; lng++; - char *longEorW = lng; + longEorW = lng; while (*longEorW != ' ') longEorW++; *longEorW++ = '\0'; - currentMark->wp = waypt_new(); + if (!currentMark->wp) + currentMark->wp = waypt_new(); currentMark->wp->latitude = atof(lat); if (*latNorS == 'S') currentMark->wp->latitude = -currentMark->wp->latitude; currentMark->wp->longitude = atof(lng); if (*longEorW == 'W') currentMark->wp->longitude = -currentMark->wp->longitude; + xfree(position); } } else if (0 == strcmp(element, "Name")) { // Names we care about may be either for routes or marks - char *name = xstrdup(s); - if (inMark == 1) - currentMark->wp->shortname = name; - else if (inRoute == 1) - currentRoute->r->rte_name = name; + if (inMark) + { + if (!currentMark->wp) + currentMark->wp = waypt_new(); + currentMark->wp->shortname = xstrdup(s); + + // Also set the creation time + if (currentMark->created) + { + struct tm t; + char yearString[5], monthString[3], dayString[3], hourString[3], minString[3], secString[3]; + memset(&t, 0, sizeof(struct tm)); + strncpy(yearString, currentMark->created, 4); + yearString[4] = '\0'; + t.tm_year = atoi(yearString) - 1900; + strncpy(monthString, currentMark->created+4, 2); + monthString[3] = '\0'; + t.tm_mon = atoi(monthString) - 1; + strncpy(dayString, currentMark->created+6, 2); + dayString[3] = '\0'; + t.tm_mday = atoi(dayString); + strncpy(hourString, currentMark->created+9, 2); + hourString[3] = '\0'; + t.tm_hour = atoi(hourString); + strncpy(minString, currentMark->created+11, 2); + minString[3] = '\0'; + t.tm_min = atoi(minString); + strncpy(secString, currentMark->created+13, 2); + secString[3] = '\0'; + t.tm_sec = atoi(secString); + currentMark->wp->creation_time = mktime(&t); + } + } + else if (inRoute) + currentRoute->r->rte_name = xstrdup(s); } else if (0 == strcmp(element, "Description")) { // Descriptions we care about may be either for routes or marks char *desc = xstrdup(s); - if (inMark == 1) + if (inMark) + { + if (!currentMark->wp) + currentMark->wp = waypt_new(); currentMark->wp->description = desc; - else if (inRoute == 1) + } + else if (inRoute) currentRoute->r->rte_desc = desc; } @@ -238,6 +289,8 @@ void ce_rd_init(const char *fname) { fd = xfopen(fname, "r", MYNAME); + QUEUE_INIT(&ce_route_head); + QUEUE_INIT(&ce_mark_head); psr = XML_ParserCreate(NULL); if (!psr) { @@ -246,6 +299,7 @@ ce_rd_init(const char *fname) XML_SetElementHandler(psr, ce_start, ce_end); cdatastr = xcalloc(MY_CBUF,1); + element = xcalloc(MY_CBUF,1); XML_SetCharacterDataHandler(psr, ce_cdata); } @@ -273,22 +327,22 @@ ce_read(void) void ce_fix_waypoints(void) { - ce_route *route = routes; - while (route != NULL) { - ce_mark *mark = route->marks; - while (mark != NULL) { - ce_mark *mark2 = marks; - while (mark2 != NULL) { + queue *elem, *tmp; + QUEUE_FOR_EACH(&ce_route_head, elem, tmp) { + ce_route *route = (ce_route *) elem; + queue *elem2, *tmp2; + QUEUE_FOR_EACH(&route->ce_mark_head, elem2, tmp2) { + ce_mark *mark = (ce_mark *) elem2; + queue *elem3, *tmp3; + QUEUE_FOR_EACH(&ce_mark_head, elem3, tmp3) { + ce_mark *mark2 = (ce_mark *) elem3; if (0 == strcmp(mark->id, mark2->id)) { - mark->wp = mark2->wp; + mark->wp = waypt_dupe(mark2->wp); mark2->used = 1; break; } - mark2 = mark2->next; } - mark = mark->next; } - route = route->next; } } @@ -296,19 +350,16 @@ ce_fix_waypoints(void) void ce_check_route_names(void) { - ce_route *route = routes; - while (route != NULL) { + queue *elem, *tmp; + QUEUE_FOR_EACH(&ce_route_head, elem, tmp) { + ce_route *route = (ce_route *) elem; if (route->r->rte_name == NULL) { - cdatastr = '\0'; - strcat(cdatastr, marks->wp->shortname); + *cdatastr = '\0'; + strcat(cdatastr, ((ce_mark *) QUEUE_FIRST(&route->ce_mark_head))->wp->shortname); strcat(cdatastr, "->"); - ce_mark *mark = route->marks; - while (mark->next != NULL) - mark = mark->next; - strcat(cdatastr, mark->wp->shortname); + strcat(cdatastr, ((ce_mark *) QUEUE_LAST(&route->ce_mark_head))->wp->shortname); route->r->rte_name = xstrdup(cdatastr); } - route = route->next; } } @@ -316,18 +367,16 @@ ce_check_route_names(void) void ce_remove_unused_marks(void) { - ce_mark *mark = marks; - ce_mark *prev_mark = NULL; - while (mark != NULL) { - if (mark->used == 1) { - if (prev_mark == NULL) - marks = mark = mark->next; - else - prev_mark->next = mark = mark->next; - continue; + queue *elem, *tmp; + QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) { + ce_mark *mark = (ce_mark *) elem; + if (mark->used) + { + dequeue(elem); + if (mark->wp) + waypt_free(mark->wp); + free_mark(mark); } - prev_mark = mark; - mark = mark->next; } } @@ -335,27 +384,27 @@ ce_remove_unused_marks(void) void ce_print_results(void) { - ce_route *curr_route = routes; - while (curr_route != NULL) { - printf("Route name=%s id=%s\n", curr_route->r->rte_name, curr_route->id); - ce_mark *curr_mark = curr_route->marks; - while (curr_mark != NULL) { - if (curr_mark->wp == NULL) + queue *elem, *tmp; + QUEUE_FOR_EACH(&ce_route_head, elem, tmp) { + queue *elem2, *tmp2; + ce_route *route = (ce_route *) elem; + printf("Route name=%s id=%s\n", route->r->rte_name, route->id); + QUEUE_FOR_EACH(&route->ce_mark_head, elem2, tmp2) { + ce_mark *mark = (ce_mark *) elem2; + if (mark->wp == NULL) printf(" null\n"); else - printf(" %s (%f, %f)\n", curr_mark->wp->shortname, curr_mark->wp->latitude, curr_mark->wp->longitude); - curr_mark = curr_mark->next; + printf(" %s (%f, %f)\n", mark->wp->shortname, mark->wp->latitude, mark->wp->longitude); } - curr_route = curr_route->next; } - ce_mark *curr_mark = marks; - while (curr_mark != NULL) { - printf("Mark name=%s id=%s ", curr_mark->wp->shortname, curr_mark->id); - if (curr_mark->wp == NULL) + + QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) { + ce_mark *mark = (ce_mark *) elem; + printf("Mark name=%s id=%s ", mark->wp->shortname, mark->id); + if (mark->wp == NULL) printf("(null)\n"); else - printf("(%f, %f)\n", curr_mark->wp->latitude, curr_mark->wp->longitude); - curr_mark = curr_mark->next; + printf("(%f, %f)\n", mark->wp->latitude, mark->wp->longitude); } } @@ -363,37 +412,48 @@ ce_print_results(void) void ce_rd_deinit(void) { + queue *elem, *tmp; + ce_fix_waypoints(); ce_check_route_names(); ce_remove_unused_marks(); // ce_print_results(); // Add routes to GPSBabel - ce_route *route = routes; - while (route != NULL) { + QUEUE_FOR_EACH(&ce_route_head, elem, tmp) { + ce_route *route = (ce_route *) elem; + queue *elem2, *tmp2; route_add_head(route->r); - ce_mark *mark = route->marks; - while (mark->next != NULL) { - route_add_wpt(route->r, mark->wp); - mark = mark->next; + QUEUE_FOR_EACH(&route->ce_mark_head, elem2, tmp2) { + ce_mark *mark = (ce_mark *) elem2; + if (mark->wp) + route_add_wpt(route->r, mark->wp); + else + printf("Undefined mark: %s\n", mark->id); } - route = route->next; + free_route(route); } // Add (unused) marks to GPSBabel - ce_mark *mark = marks; - while (mark != NULL) { + QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) { + ce_mark *mark = (ce_mark *) elem; waypt_add(mark->wp); - mark = mark->next; + free_mark(mark); } fclose(fd); + xfree(element); + xfree(cdatastr); } void ce_wr_init(const char *fname) { - fatal(MYNAME ": Does not support writing CoastalExplorer files.\n"); + mkshort_handle = mkshort_new_handle(); + QUEUE_INIT(&ce_mark_head); + time_buffer = xcalloc(MY_TBUF,1); + uuid_buffer = xcalloc(MY_UBUF,1); + ofd = xfopen(fname, "w", MYNAME); } @@ -401,11 +461,112 @@ void ce_wr_deinit(void) { fclose(ofd); + mkshort_del_handle(mkshort_handle); + xfree(time_buffer); + xfree(uuid_buffer); +} + +static char * +ce_gen_creation_time(time_t tm) +{ + struct tm *t = localtime(&tm); + sprintf(time_buffer, "%04d%02d%02dT%02d%02d%02dZ", t->tm_year+1900, t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec); + return time_buffer; +} + +static char * +ce_gen_current_time(void) +{ + return ce_gen_creation_time(current_time()); +} + +static char * +ce_gen_uuid(void) +{ + uuid_t uu; + uuid_generate(uu); + sprintf(uuid_buffer, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", + uu[0], uu[1], uu[2], uu[3], uu[4], uu[5], uu[6], uu[7], + uu[8], uu[9], uu[10], uu[11], uu[12], uu[13], uu[14], uu[15]); + return uuid_buffer; +} + +static void +ce_route_hdr(const route_head *rte) +{ + fprintf(ofd, "\t\n", ce_gen_current_time(), ce_gen_uuid()); + fprintf(ofd, "\t\t\n"); +} + +static void +ce_route_disp(const waypoint *waypointp) +{ + char *uuid = ce_gen_uuid(); + char *id = xcalloc(strlen(uuid)+3, 1); + sprintf(id, "{%s}", uuid); + currentMark = (ce_mark *) xcalloc(sizeof (ce_mark), 1); + currentMark->id = id; + currentMark->wp = (waypoint *) waypointp; + ENQUEUE_TAIL(&ce_mark_head, ¤tMark->Q); + fprintf(ofd, "\t\t\t%s\n", id); +} + +static void +ce_route_tlr(const route_head *rte) +{ + fprintf(ofd, "\t\t\n"); + if (rte->rte_name) + fprintf(ofd, "\t\t%s\n", rte->rte_name); + fprintf(ofd, "\t\n"); +} + +static void +ce_waypt_pr(const waypoint *waypointp) +{ +} + +static void +ce_mark_pr(void) +{ + queue *elem, *tmp; + QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) { + ce_mark *mark = (ce_mark *) elem; + double latitude = mark->wp->latitude; + char NorS = 'N'; + char EorW = 'E'; + double longitude = mark->wp->longitude; + fprintf(ofd, "\t\n", ce_gen_creation_time(mark->wp->creation_time), mark->id); + if (latitude < 0) { + latitude = -latitude; + NorS = 'S'; + } + if (longitude < 0) { + longitude = -longitude; + EorW = 'W'; + } + fprintf(ofd, "\t\t%3.6f %c %3.6f %c\n", latitude, NorS, longitude, EorW); + if (mark->wp->shortname) + fprintf(ofd, "\t\t%s\n", mark->wp->shortname); + fprintf(ofd, "\t\n"); + free_mark(mark); + } } void ce_write(void) { + setshort_whitespace_ok(mkshort_handle, 0); + setshort_length(mkshort_handle, 32); + + fprintf(ofd, "\n"); + fprintf(ofd, "Navigation Objects\n"); + + route_disp_all(ce_route_hdr, ce_route_tlr, ce_route_disp); + ce_mark_pr(); + waypt_disp_all(ce_waypt_pr); + + fprintf(ofd, "\n"); } ff_vecs_t coastexp_vecs = { diff --git a/gpsbabel/reference/coastexp.ref b/gpsbabel/reference/coastexp.ref index 24568428b..bdbfaa07f 100755 --- a/gpsbabel/reference/coastexp.ref +++ b/gpsbabel/reference/coastexp.ref @@ -8,141 +8,169 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/ + PESCDR01 PESCDR01 PESCDR01 + PIGEON01 PIGEON01 PIGEON01 + ANONUV01 ANONUV01 ANONUV01 + SCRUZ01 SCRUZ01 SCRUZ01 + SCRUZ02 SCRUZ02 SCRUZ02 + SCRUZENT SCRUZENT SCRUZENT + CYPRSSPT CYPRSSPT CYPRSSPT + PTSUR PTSUR PTSUR + COOPERPT COOPERPT COOPERPT + PFEIFENT PFEIFENT PFEIFENT + PFEIFANC PFEIFANC PFEIFANC + SANMRT01 SANMRT01 SANMRT01 + PDRSBLNC PDRSBLNC PDRSBLNC + SNSMNENT SNSMNENT SNSMNENT + SNSMNANC SNSMNANC SNSMNANC + CAMBRIA CAMBRIA CAMBRIA + PTESTERO PTESTERO PTESTERO + PTBUCHON PTBUCHON PTBUCHON + PTSAL01 PTSAL01 PTSAL01 + PTSALENT A description of the Point Sal Entrance mark A description of the Point Sal Entrance mark + PTSALANC PTSALANC PTSALANC + PURSMAPT PURSMAPT PURSMAPT + PTARGLLO PTARGLLO PTARGLLO + SANMGL01 SANMGL01 SANMGL01 + SANMGL02 SANMGL02 SANMGL02 + SANMGL03 SANMGL03 SANMGL03 + ADCOVENT ADCOVENT ADCOVENT + ADCOVANC ADCOVANC ADCOVANC @@ -150,31 +178,44 @@ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/ Into The Bay + SFBALBAY + SFBAY001 + SFBAY002 + SFGGBRDG + SFCHNL01 + HMCOLREF + HMPILL01 + HMPILLPT + HMPILL02 + + + HMPILL03 + diff --git a/gpsbabel/testo b/gpsbabel/testo index 82658b27c..cd772eead 100755 --- a/gpsbabel/testo +++ b/gpsbabel/testo @@ -407,6 +407,18 @@ ${PNAME} -i coastexp -f reference/coastexp.nob -o gpx -F ${TMPDIR}/coastexp.gpx compare ${TMPDIR}/coastexp.gpx reference/coastexp.ref # +# +# CoastalExplorer.. +${PNAME} -r -i coastexp -f reference/coastexp.nob -o gpx -F ${TMPDIR}/coastexp.gpx +compare ${TMPDIR}/coastexp.gpx reference/coastexp.ref +${PNAME} -r -i gpx -f ${TMPDIR}/coastexp.gpx -o coastexp -F ${TMPDIR}/coastexp.nob +compare ${TMPDIR}/coastexp.nob reference/coastexp.ref2 +${PNAME} -w -i coastexp -f reference/coastexp.nob -o gpx -F ${TMPDIR}/coastexp.gpx +compare ${TMPDIR}/coastexp.gpx reference/coastexp.ref3 +${PNAME} -w -i gpx -f ${TMPDIR}/coastexp.gpx -o coastexp -F ${TMPDIR}/coastexp.nob +compare ${TMPDIR}/coastexp.nob reference/coastexp.ref4 +# + # PsiTrex. A text format that can't be handled by XCSV due to context of # data based on other data values in the file # Waypoints first diff --git a/gpsbabel/xmlgeneric.c b/gpsbabel/xmlgeneric.c index 770362ef6..14e254bbf 100644 --- a/gpsbabel/xmlgeneric.c +++ b/gpsbabel/xmlgeneric.c @@ -36,6 +36,12 @@ static xg_tag_mapping *xg_tag_tbl; #define MYNAME "XML Reader" +void +write_xml_header(FILE *ofd) +{ + fprintf(ofd, "\n"); +} + void write_xml_entity(FILE *ofd, const char *indent, const char *tag, const char *value) @@ -53,6 +59,37 @@ write_optional_xml_entity(FILE *ofd, const char *indent, write_xml_entity(ofd, indent, tag, value); } +void +write_xml_entity_begin0(FILE *ofd, const char *indent, + const char *tag) +{ + fprintf(ofd, "%s<%s>\n", indent, tag); +} + +void +write_xml_entity_begin1(FILE *ofd, const char *indent, + const char *tag, const char *attr, + const char *attrval) +{ + fprintf(ofd, "%s<%s %s=\"%s\">\n", indent, tag, attr, attrval); +} + +void +write_xml_entity_begin2(FILE *ofd, const char *indent, + const char *tag, const char *attr1, + const char *attrval1, const char *attr2, + const char *attrval2) +{ + fprintf(ofd, "%s<%s %s=\"%s\" %s=\"%s\">\n", indent, tag, attr1, attrval1, attr2, attrval2); +} + +void +write_xml_entity_end(FILE *ofd, const char *indent, + const char *tag) +{ + fprintf(ofd, "%s\n", indent, tag); +} + void xml_write_time(FILE *ofd, const time_t timep, char *elname) { -- 2.30.2